package com.wayz.service;

import com.wayz.constants.ViewMap;
import com.wayz.entity.pojo.function.DFunctionVersion;
import com.wayz.entity.redis.play.RFunctionVersion;
import com.wayz.entity.vo.function.FunctionVersionVo;
import com.wayz.exception.WayzException;
import com.wayz.mapper.DFunctionVersionDAO;
import com.wayz.redis.BeanIdKeyEnum;
import com.wayz.redis.RFunctionVersionObject;
import com.wayz.redis.RedisUtils;
import com.wayz.util.TimeHelper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


/**
 * 功能版本服务实现类
 *
 * @author wade.liu@wayz.ai
 */
//@Service("functionVersionService")
@Service(version = "1.0.0", protocol = "dubbo")
@RefreshScope
public class FunctionVersionServiceImpl implements FunctionVersionService {

    /**
     * DAO 相关
     */
    @Resource(name = "dFunctionVersionDAO")
    private DFunctionVersionDAO dFunctionVersionDAO;

    /**
     * 服务相关
     */
    @Autowired
    private RoleSaasService roleSaasService = null;
    @Autowired
    private MenuSaasService menuSaasService = null;
    @Autowired
    private CompanySaasService companySaasService = null;

    /**
     * redis相关
     */
    @Resource(name = "redisUtils")
    private RedisUtils redisUtils;
    /**
     * 功能版本缓存
     */
    @Resource(name = "rFunctionVersionObject")
    private RFunctionVersionObject rFunctionVersionObject;

    /**
     * 查询功能版本
     *
     * @param myId 我的客户标识
     * @return 版本列表
     * @throws WayzException 平台异常
     */
    @Override
    public List<FunctionVersionVo> queryFunctionVersion(Long myId, String name) throws WayzException {
        // 初始化
        List<DFunctionVersion> dFunctionVersionList = dFunctionVersionDAO.queryAllFunctionVersion(name);
        List<FunctionVersionVo> versionList = new ArrayList<>(dFunctionVersionList.size());
        FunctionVersionVo functionVersion;
        for (DFunctionVersion dFunctionVersion : dFunctionVersionList) {
            functionVersion = new FunctionVersionVo();
            BeanUtils.copyProperties(dFunctionVersion, functionVersion);
            functionVersion.setCreatedTime(TimeHelper.getTimestamp(dFunctionVersion.getCreatedTime()));
            versionList.add(functionVersion);
        }
        // 返回数据
        return versionList;
    }

    /**
     * 创建功能版本
     *
     * @param myId            我的客户标识
     * @param name            版本名称
     * @param description     描述
     * @param userLimit       用户数限制
     * @param materialLimit   素材空间限制
     * @param singleFileLimit 单个文件大小限制
     * @return 版本标识
     * @throws WayzException 平台异常
     */
    @Override
    public Long createFunctionVersion(Long myId, String name, String description, Integer userLimit,
                                      Long materialLimit, Long singleFileLimit) throws WayzException {

        Integer count = dFunctionVersionDAO.countVersionByName(name);
        if (count > 0) {
            throw new WayzException("版本名已存在");
        }
        // 创建版本管理员角色
        Long roleId = this.insertVersionRole(name + "版本管理员");

        // 存储版本信息
        Long id = this.insertVersionToDB(name, description, roleId, userLimit, materialLimit, singleFileLimit);
        // 维护缓存
        RFunctionVersion rFunctionVersion = new RFunctionVersion();
        rFunctionVersion.setName(name);
        rFunctionVersion.setDescription(description);
        rFunctionVersion.setMaterialLimit(1024 * 1024 * materialLimit);
        rFunctionVersion.setRoleId(roleId);
        rFunctionVersion.setSingleFileLimit(1024 * 1024 * singleFileLimit);
        rFunctionVersion.setUserLimit(userLimit);
        rFunctionVersionObject.set(id, rFunctionVersion);

        // 返回数据
        return id;
    }

    /**
     * 创建版本管理员角色 TODO??
     *
     * @param roleDescription
     */
    private Long insertVersionRole(String roleDescription) throws WayzException {
        return roleSaasService.createVersionRole(roleDescription);
    }

    /**
     * 给管理员角色授权
     *
     * @param versionId  版本标识
     * @param menuIdList 权限菜单列表
     */
    @Override
    public void setVersionMenuList(Long myId, Long versionId, List<Long> menuIdList) throws WayzException {
        // 获取角色
        Long roleId = rFunctionVersionObject.getLong(versionId, RFunctionVersion.ROLEID);

        // 删除角色菜单
        roleSaasService.deleteMenuRoleId(roleId);
        // 设置权限
        menuIdList.add(0L);
        roleSaasService.authorityRoleSaaa(roleId, menuIdList);
    }

    /**
     * 写入版本数据到数据库
     *
     * @param name
     * @param description
     * @param userLimit       用户数限制
     * @param materialLimit   素材空间限制
     * @param singleFileLimit 单个文件大小限制
     * @param roleId
     */
    private Long insertVersionToDB(String name, String description, Long roleId, Integer userLimit, Long materialLimit,
                                   Long singleFileLimit) throws WayzException {
        DFunctionVersion create = new DFunctionVersion();
        Long id = redisUtils.incrBy(BeanIdKeyEnum.VERSION_ADMIN.getKey(), RedisUtils.STEP_SIZE);
        create.setId(id);
        create.setName(name);
        create.setDescription(description);
        create.setRoleId(roleId);
        create.setUserLimit(userLimit);
        create.setMaterialLimit(1024 * 1024 * materialLimit);
        create.setSingleFileLimit(1024 * 1024 * singleFileLimit);
        dFunctionVersionDAO.create(create);
        return id;
    }

    /**
     * 修改功能版本
     *
     * @param myId            我的客户标识
     * @param id              版本标识
     * @param name            版本名称
     * @param description     描述
     * @param userLimit       用户数限制
     * @param materialLimit   素材空间限制
     * @param singleFileLimit 单个文件大小限制
     * @throws WayzException 平台异常
     */
    @Override
    public void modifyFunctionVersion(Long myId, Long id, String name, String description, Integer userLimit,
                                      Long materialLimit, Long singleFileLimit) throws WayzException {
        DFunctionVersion version = dFunctionVersionDAO.getVersionByName(name);
        if (version != null && !version.getId().equals(id)) {
            throw new WayzException("版本名称已存在");
        }

        DFunctionVersion modify = new DFunctionVersion();
        modify.setId(id);
        modify.setName(name);
        modify.setDescription(description);
        modify.setUserLimit(userLimit);
        modify.setMaterialLimit(1024 * 1024 * materialLimit);
        modify.setSingleFileLimit(1024 * 1024 * singleFileLimit);
        dFunctionVersionDAO.modify(modify);

        // 维护缓存
        RFunctionVersion rFunctionVersion = new RFunctionVersion();
        rFunctionVersion.setName(name);
        rFunctionVersion.setRoleId(version.getRoleId());
        rFunctionVersion.setDescription(description);
        rFunctionVersion.setMaterialLimit(1024 * 1024 * materialLimit);
        rFunctionVersion.setSingleFileLimit(1024 * 1024 * singleFileLimit);
        rFunctionVersion.setUserLimit(userLimit);
        rFunctionVersionObject.set(id, rFunctionVersion);
    }

    /**
     * 删除功能版本
     *
     * @param myId 我的客户标识
     * @param id   版本标识
     * @throws WayzException 平台异常
     */
    @Override
    public void deleteFunctionVersion(Long myId, Long id) throws WayzException {
        // 验证是否有公司使用
        Integer count = companySaasService.countCompanyByVersionId(id);
        if (count > 0) {
            throw new WayzException("有" + count + "家公司正在使用此版本，不能删除版本");
        }
        // 删除角色
        Long roleId = rFunctionVersionObject.getLong(id, RFunctionVersion.ROLEID);
        roleSaasService.deleteVersionRole(roleId);
        // 删除菜单权限关联
        roleSaasService.deleteMenuRoleId(roleId);
        // 删除版本
        dFunctionVersionDAO.deleteVersionById(id);
    }

    /**
     * 根据Id获取版本管理员角色Id
     *
     * @param myId
     * @param versionId
     * @return
     */
    @Override
    public Long getRoleIdByVersionId(Long myId, Long versionId) {
        return dFunctionVersionDAO.getRoleIdById(versionId);
    }

    /**
     * 查询功能版本视图
     *
     * @param myId
     * @return
     * @throws WayzException
     */
    @Override
    public List<ViewMap> queryVersionView(Long myId) {
        return dFunctionVersionDAO.queryVersionViewMap();
    }

    /**
     * 查询版本信息
     *
     * @param myId
     * @param id
     * @return
     */
    @Override
    public FunctionVersionVo getVersion(Long myId, Long id) {
        DFunctionVersion version = dFunctionVersionDAO.getVersionById(id);
        FunctionVersionVo functionVersionVo = new FunctionVersionVo();
        BeanUtils.copyProperties(version, functionVersionVo);
        if (version.getCreatedTime() != null) {
            functionVersionVo.setCreatedTime(TimeHelper.getTimestamp(version.getCreatedTime()));
        }
        if (version.getModifiedTime() != null) {
            functionVersionVo.setModifiedTime(TimeHelper.getTimestamp(version.getModifiedTime()));
        }
        return functionVersionVo;
    }
}
